<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Guerra no espa&ccedil;o</title>
</head>
<body>

	<h1>Guerra no espa&ccedil;o</h1>

	<table>

		<tr>
			<td id="campoPontos">Pontos: 0</td>
			<td id="campoMeta">Meta: 100</td>
			<td id="campoFase">Fase: 1</td>
			<td id="campoVidas">Vidas: 3</td>
		</tr>
		<tr>
			<td colspan=3><canvas id="surface" width="640" height="480"
					style="background-color: #ccc;"></canvas></td>
			<td>
				<b>Comandos:</b>
				</br><b>Barra de espa&ccedil;o </b>- Atirar
				</br><b>P </b>- Pausar
				</br><b>I </b>- Iniciar Jogo
				</br><b>R </b>- Reiniciar Jogo
			</td>
		</tr>



		<script type="text/javascript">
window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function(/* function */ callback, /* DOMElement */ element){
                window.setTimeout(callback, 1000 / 60);
              };
})();

var canvas = document.getElementById("surface");
var ctx = canvas.getContext("2d");

function atualizarVidas(){
	var campoVida = document.getElementById("campoVidas");
	campoVida.innerHTML = 'Vidas: ' + qtdVidas; 	
}

function atualizarFase(){
	var campoFase = document.getElementById("campoFase");
	campoFase.innerHTML = 'Fase: ' + fase;
}

function atualizarPontos(){
	var campoPontos = document.getElementById("campoPontos");
	campoPontos.innerHTML = 'Pontos: ' + pontos;	
	var campoMeta = document.getElementById("campoMeta");
	campoMeta.innerHTML = 'Meta: ' + metaPontuacao;	
}


/*********** STATUS DO JOGO ***********/
var qtdVidas = 3; 			//Variavel que indica a quantidade de vidas do jogador
var fase = 1; 				//Variavel que indica a fase atual do jogo
var pontos = 0;				//Variavel que indica a quantidade pontos do jogador
var metaPontuacao = 100;	//Variavel que indica a quantidade necessaria para o jogador passar de fase
var vidaExtra = 500;		//Variavel que indica a quantidade pontos necessario para adquirir uma vida extra 

/*********** VELOCIDADES DAS NAVES E DOS TIROS ***********/ 
var movimentoDevagar = 0.7; //Variavel para a velocidade da nave do tipo lenta
var movimentoNormal = 1.3;	//Variavel para a velocidade da nave do tipo normal
var movimentoRapido = 1.8;	//Variavel para a velocidade da nave do tipo rapida
var movimentoTiro = 2.1;		//Variavel para a velocidade do tiro

/*********** INFORMACOES SOBRE A COLISAO ***********/
var distanciaColisao = 28; 	//Variavel que indica a distancia necessaria entre uma nave e outra para colidir


/*********** MAPA DA POSICAO X e MAPA DA POSICAO Y ***********/
var mapaX = new Array(); 	//Variavel referente as posicoes X do mapa
var mapaY = new Array();	//Varaivel referente as posicoes Y do mapa


/*********** INCIALIZACAO DO JOGO ***********/
var jogador = new NaveJogo();			//Variavel referente ao jogado
jogador.x = canvas.width/2-23;			//Posicao X inicial do jogador
jogador.y = canvas.height/2;			//Posicao Y inicial do jogador
jogador.angulo = 0;						//Angulo inicial do jogador
jogador.tipo = 'jogador';				//Tipo da nave do jogador
jogador.velocidade = movimentoNormal;	//Velocidade da nave do jogador
jogador.qtdBalas = 0;						//Lista de tiros do jogador
 
var inimigos = new Array();				//Lista de inimigos na tela
var balas = new Array();				//Lista de tiros na tela
var pressionado = -1;					//Atributo para verificar se o jogador fez alguma movimentação enquanto estava entre uma parede
var qtdMaxInimigos = 3; 				//Variavel que indica a quantidade maxima de inimigos na tela

/**
Função utilizada para criar um novo inimigo na tela
*/
function gerarInimigo(){
	if (inimigos.length < qtdMaxInimigos){
		var inimigo = new NaveJogo();
		
		var posX = parseInt((Math.random() * (mapaX.length-2))) + 1;
		var posY= parseInt((Math.random() * (mapaY.length-2))) + 1;
		
		var angulos = [0, 90, 180, 270];
		inimigo.angulo = angulos[parseInt(Math.random() * 4)];
		
		switch(inimigo.angulo){
			case 0:{
				inimigo.x = mapaX[posX] + 20;
				inimigo.y = canvas.height;
				break;
			}
			case 90:{
				inimigo.x = 0;
				inimigo.y = mapaY[posY] + 34;
				break;
			}
			case 180:{
				inimigo.x = mapaX[posX] + 20;
				inimigo.y = 0;
				break;
			}
			case 270:{
				inimigo.x = canvas.width;
				inimigo.y = mapaY[posY] + 34;
				break;
			}	
		}	
		
		var tipoAviao = parseInt((Math.random() * 3));
		switch(tipoAviao){
			case 0:{
				inimigo.tipo = 'devagar';
				inimigo.velocidade = movimentoDevagar;
				break;
			}
			case 1:{
				inimigo.tipo = 'devagarAtira';
				inimigo.velocidade = movimentoDevagar;
				break;
			}
			case 2:{
				inimigo.tipo = 'rapidoAtira';
				inimigo.velocidade = movimentoRapido;
				break;
			}	
		}	
		inimigos[inimigos.length] = inimigo;	
	}
}

/**
Estrutura de uma nave com as posições x,y,angulo, tipo da nave, a velocidade da nave e a sua lista de balas
*/
function NaveJogo() {
		this.x = 257;
		this.y = 380;
		this.angulo = 0;
		this.tipo = 'devagar';
		this.velocidade = movimentoNormal;
		this.qtdBalas = 0;
}

/**
Estrutura da bala com as posições x,y,angulo, altura e largura, velocidade e se a origem da bala foi de um jogador ou de um inimigo
*/
function Bala(x, y, angulo, origem){
	this.x = x;
	this.y = y;
	this.angulo = angulo;
	this.width = 3;
	this.height = 12;
	this.velocidade = movimentoTiro;
	this.origem = origem;
}


//Inicializa o array do mapa do caminho
var i = 0;
for (x = 0; x <=canvas.width; x += 39) {
	mapaX[i] = x;
	i++;
}
i = 0;
for (y = 0; y <=canvas.height; y += 50) {					
	mapaY[i] = y;
	i++;
}
		


var planeImage = new Image();
planeImage.src = "red-airplane.png";

planeImage.addEventListener("load", desenha());

//desenha o mapa do caminho na tela	
function desenha() {
		ctx.save();
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		for (x = 0; x < mapaX.length; x += 1) {
			for (y = 0; y < mapaY.length; y += 1) {					
				ctx.fillRect(mapaX[x], mapaY[y], 5, 20);	
			}
		}
		ctx.restore();
}

/**
Função que recebe uma nave com parametro e desenha esta nave na tela escolhendo a imagem a depender do tipo da nave. 
 */
function redesenharNave(nave){
	ctx.save();
	ctx.translate(nave.x, nave.y);
	ctx.rotate(nave.angulo * Math.PI/180);
	if(nave.tipo == 'jogador'){
		ctx.drawImage(planeImage, 0, 0, 26, 25, -13, -13, 25, 26);
	}else if(nave.tipo == 'devagar'){
		ctx.drawImage(planeImage, 52, 0, 26, 25, -13, -13, 25, 26);
	}else if(nave.tipo == 'devagarAtira'){
		ctx.drawImage(planeImage, 78, 0, 26, 25, -13, -13, 25, 26);
	}else if(nave.tipo == 'rapidoAtira'){
		ctx.drawImage(planeImage, 26, 0, 26, 25, -13, -13, 25, 26);
	}
	ctx.restore();
}

/**
 Função que percorre a lista de balas e as desenha na tela
 */
function desenhaBalas(){

	verificaLimiteTelaBala();
	verificaColisaoBalaNoJogador();
	verificaColisaoBalaNoInimigo();
	for (i = 0; i < balas.length; i += 1) {
		if (balas[i].angulo == 0){
			balas[i].y -= balas[i].velocidade;
		}
		if (balas[i].angulo == 90){
			balas[i].x += balas[i].velocidade;
		}
		if (balas[i].angulo == 180){
			balas[i].y += balas[i].velocidade;
		}
		if (balas[i].angulo == 270){
			balas[i].x -= balas[i].velocidade;
		}		
		ctx.save();
		ctx.translate(balas[i].x, balas[i].y);
		ctx.rotate(balas[i].angulo * Math.PI/180);
		if(balas[i].origem.tipo == 'jogador'){
			ctx.fillStyle = "rgba(255, 0, 0, 255)";
		}else if(balas[i].origem.tipo == 'devagarAtira'){
			ctx.fillStyle = "rgba(0, 255, 0, 255)";
		}else if(balas[i].origem.tipo == 'rapidoAtira'){
			ctx.fillStyle = "rgba(255, 255, 0, 255)";
		}
		ctx.fillRect(0, 0, balas[i].width, balas[i].height);
		ctx.restore();
	}
}
	
function colidiuX(nave){
	var colidiu = false;
		for ( i = 0; i < mapaX.length; i++ ){
			if( nave.x >= (mapaX[i] -13) & nave.x <= (mapaX[i] + 18)){					
				colidiu = true;
			}
		}
	return colidiu;
}
	
function colidiuY(nave){
	var colidiu = false;
		for ( i = 0; i < mapaY.length; i++ ){
			if ( nave.y >= (mapaY[i] -13) & nave.y <= (mapaY[i] + 33)){				
				colidiu = true;
			}
		}
	return colidiu;
}


var inimigoColidido = false;
function colidiuInimigo(){
	inimigoColidido = false;	
	for(var i=0; i<inimigos.length; i++) {
		if((jogador.x + distanciaColisao >= inimigos[i].x && jogador.x-distanciaColisao <= inimigos[i].x) && (jogador.y+distanciaColisao >= inimigos[i].y && jogador.y-distanciaColisao <=inimigos[i].y)) {
			inimigos.splice(i, 1);
			inimigoColidido = true;
		}
	}
		
	if(inimigoColidido) {
		qtdVidas = qtdVidas - 1;
		if(qtdVidas <= 0){
			gameOver();
			
			reiniciarJogo();
		}else{
			atualizarStatus();
			reiniciarJogo();
		}
	}
}
	

function atualizarStatus(){
	atualizarVidas();
	atualizarFase();
	atualizarPontos();
}

function iniciarJogo(){
	qtdVidas = 3;
	fase = 1;
	pontos = 0;
	metaPontuacao = 100;
	inimigos = new Array();
	balas = new Array();
	qtdMaxInimigos = 3;
	atualizarStatus();
	clearInterval(intervaloGeracaoInimigo);
}

function gameOver(){
	alert("Game-Over");
	iniciarJogo();
	jogoIniciado = false;
}

function reiniciarJogador(){
	jogador.x = canvas.width/2-23;
	jogador.y = canvas.height/2;
	jogador.angulo = 0;
}

function reiniciarJogo(){
	reiniciarJogador();
	var intervaloGeracaoInimigo = window.setInterval(gerarInimigo, 6000);
}
var jogoPausado = false;
var jogoIniciado = false;
window.addEventListener("keydown", function(e) {
	//Barra de espaço = 32
	// P = 80
	if (e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40){
		if((jogoPausado == false) && (jogoIniciado == true)){
			pressionado = e.keyCode; 
		}
	}
	if (e.keyCode == 32){
		if((jogoPausado == false) && (jogoIniciado == true)){
			efetuarDisparo(jogador);
		}
	}
	if (e.keyCode == 80){
			jogoPausado = !jogoPausado;
	}
	
	if (e.keyCode == 82){
		if(jogoPausado == false){
			jogoIniciado = true;
			jogoPausado = false;
			iniciarJogo();
			reiniciarJogo();
			inimigos = new Array();
		}
	}
	
	if (e.keyCode == 73){
		jogoIniciado = true;
	}
});

function efetuarDisparo(nave){	
	var numMaxBalas = 1;	
	if (nave.tipo == "jogador"){
		numMaxBalas = 2;
	}
	
	if(nave.qtdBalas <= numMaxBalas){
		if (nave.angulo == 0){
			var novaBala = new Bala(nave.x - 2, nave.y - 20, nave.angulo, nave); 
			balas.push(novaBala);
			nave.qtdBalas += 1;
		}
		if (nave.angulo == 90){
			var novaBala = new Bala(nave.x + 20, nave.y - 2, nave.angulo, nave); 
			balas.push(novaBala);
			nave.qtdBalas += 1;
		}
		if (nave.angulo == 180){
			var novaBala = new Bala(nave.x + 2, nave.y + 20, nave.angulo, nave);
			balas.push(novaBala);
			nave.qtdBalas += 1;
		}
		if (nave.angulo == 270){
			var novaBala = new Bala(nave.x - 20, nave.y + 2, nave.angulo, nave);
			balas.push(novaBala);
			nave.qtdBalas += 1;
		}
		console.log("Balas da nave "+nave.tipo+" = "+ nave.qtdBalas);
	}
	
}

function verificaColisaoBalaNoJogador(){
	//FUNCAO QUE VERIFICA COLISAO DA BALA NO JOGADOR
	var rangeX = 10;
	var rangeY = 10;
	var colidiu = 0;
	var newBalas = new Array();
	for(i = 0 ; i < balas.length; i++){
		if(balas[i].origem.tipo != "jogador"){			
			if(balas[i].x > jogador.x - rangeX && balas[i].x < jogador.x + rangeX){				
				if(balas[i].y > jogador.y - rangeY && balas[i].y < jogador.y + rangeY){					
					colidiu = 1;
					console.log("balas[i].origem.balas: " + balas[i].origem.qtdBalas);
					console.log("balas[i].origem.tipo: " + balas[i].origem.tipo);
					balas[i].origem.qtdBalas-=1;
					console.log("balas[i].origem.balas: " + balas[i].origem.qtdBalas);
					console.log("balas[i].origem.tipo: " + balas[i].origem.tipo);
				}				
			}			
		}
		if (colidiu == 1) {
			reiniciarJogo();
			console.log("bala: " + balas[i]);			
		} else {
			newBalas.push(balas[i]);
		}
	}
	if (colidiu == 1) {
			qtdVidas = qtdVidas - 1;
			if (qtdVidas <= 0) {
				gameOver();
				
			} else {
				atualizarStatus();
			}
	}
	balas = newBalas;
	
}


function verificaColisaoBalaNoInimigo() {
		var rangeX = 10;
		var rangeY = 10;
		var atingido = 0;
		for (i = 0; i < balas.length; i++) {
			for (j = 0; j < inimigos.length; j++) {
				if (balas[i].origem.tipo == "jogador") {
					if (balas[i].x > inimigos[j].x - rangeX
							&& balas[i].x < inimigos[j].x + rangeX) {
						if (balas[i].y > inimigos[j].y - rangeY
								&& balas[i].y < inimigos[j].y + rangeY) {

							if (inimigos[j].tipo == 'devagar') {
								pontos += 10;
							} else if (inimigos[j].tipo == 'devagarAtira') {
								pontos += 20;
							} else if (inimigos[j].tipo == 'rapidoAtira') {
								pontos += 30;
							}

							if (pontos >= vidaExtra) {
								qtdVidas += 1;
								vidaExtra += 500;
								atualizarVidas();
							}

							atualizarPontos();
							verificaFase();

							inimigos.splice(j, 1);
							atingido = 1;
							gerarInimigo();
						}
					}
				}
			}
			if (atingido == 1) {
				balas.splice(i, 1);
				jogador.qtdBalas -= 1;
			}
			atingido = 0;
		}
	}

	function modificaAngulo(valor, nave) {
		if (valor == 38) { //seta cima
			if (!colidiuX(nave)) {
				if (nave.y - nave.velocidade >= 15) {
					pressionado = -1;
					nave.angulo = 0;
					redesenharNave(nave);
				}
			}
		}
		if (valor == 40) { //seta baixo				
			if (!colidiuX(nave)) {
				//Detecta se ira passar da area do canvas
				if (nave.y + nave.velocidade <= canvas.height - 15) {
					pressionado = -1;
					nave.angulo = 180;
					redesenharNave(nave);
				}
			}
		}

		if (valor == 37) { //seta esquerda
			if (!colidiuY(nave)) {
				//Detecta se ira passar da area do canvas
				if (nave.x - nave.velocidade >= 15) {
					pressionado = -1;
					nave.angulo = 270;
					redesenharNave(nave);
				}
			}

		}
		if (valor == 39) { //seta direita
			if (!colidiuY(nave)) {
				if (nave.x + nave.velocidade <= canvas.width - 15) {
					pressionado = -1;
					nave.angulo = 90;
					redesenharNave(nave);
				}
			}

		}
	}

	function movimentoNave(nave) {
		if (nave.angulo == 0) {
			nave.y -= nave.velocidade;
		} else if (nave.angulo == 90) {
			nave.x += nave.velocidade;
		} else if (nave.angulo == 180) {
			nave.y += nave.velocidade;
		} else if (nave.angulo == 270) {
			nave.x -= nave.velocidade;
		}
	}

	function verificaLimiteTela(nave) {
		if (nave.y >= canvas.height) {
			nave.y = 2;
		} else if (nave.y <= 0) {
			nave.y = canvas.height;
		} else if (nave.x >= canvas.width) {
			nave.x = 0;
		} else if (nave.x <= 0) {
			nave.x = canvas.width;
		}
	}

	function verificaFase() {
		if (pontos >= metaPontuacao) {
			metaPontuacao += parseInt(metaPontuacao * 1.2);
			fase = fase + 1;
			qtdMaxInimigos = fase * 3;
			atualizarFase();
		}
	}

	function verificaLimiteTelaBala() {
		var i = 0;
		var newBalas = new Array;
		while (i < balas.length) {
			if (balas[i].y >= canvas.height || balas[i].y <= 0 || balas[i].x >= canvas.width || balas[i].x <= 0) {
				balas[i].origem.qtdBalas-=1;
				//balas.splice[i,1];				
			} else {
				newBalas.push(balas[i]);				
			} 
			
			i++;
			
		}
		balas = newBalas;
	}
	

	function dispararTiro(nave) {
		if (nave.tipo == 'devagarAtira' || nave.tipo == 'rapidoAtira') {
			var rangeX = 10;
			var rangeY = 10;

			switch (nave.angulo) {
			case 0: {
				if (jogador.x > nave.x - rangeX && jogador.x < nave.x + rangeX && jogador.y < nave.y) {					
					efetuarDisparo(nave);
				}
				break;
			}

			case 90: {
				if (jogador.y > nave.y - rangeY && jogador.y < nave.y + rangeY && jogador.x > nave.x) {
					efetuarDisparo(nave);
				}
				break;
			}
			case 180: {
				if (jogador.x > nave.x - rangeX && jogador.x < nave.x + rangeX && jogador.y > nave.y) {
					efetuarDisparo(nave);
				}
				break;
			}
			case 270: {
				if (jogador.y > nave.y - rangeY && jogador.y < nave.y + rangeY && jogador.x < nave.x) {
					efetuarDisparo(nave);
				}
				break;
			}
			}
		}

	}

	function loop() {
		if((jogoPausado == false) && (jogoIniciado == true)){
			verificaLimiteTela(jogador);
			desenha();
			desenhaBalas();
			for (i = 0; i < inimigos.length; i++) {
				verificaLimiteTela(inimigos[i]);
				movimentoNave(inimigos[i]);
				colidiuInimigo();
				if (!inimigoColidido) {
					redesenharNave(inimigos[i]);
					dispararTiro(inimigos[i]);
				}
	
			}
			movimentoNave(jogador);
			colidiuInimigo();
			if (pressionado != -1) {
				modificaAngulo(pressionado, jogador);
			}
			redesenharNave(jogador);

		}
		window.requestAnimFrame(loop, canvas);
	}

	window.requestAnimFrame(loop, canvas);
	gerarInimigo();
	var intervaloGeracaoInimigo = window.setInterval(gerarInimigo, 5000);
</script>
</body>
</html>